package com.example.zz.example.mediaplayer;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.example.remoteservice.IMyAidlInterface;
import com.example.zz.example.R;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * 服务的作用：
 * 1、新建服务，复写方法onBind，需要返回IBinder。
 * 2、当IBinder接口返回的是继承Binder并且实现自定义接口时，它是本地服务，用来与activity绑定并提供交流的通道，如：MyBinder extends Binder implements Imusic {
 * 3、当IBinder接口返回的是集成AIDL接口类时，它是一个远端服务，用来为其他进程提供多线程跨进程通信的通道，如：MyBinder extends IMyAidlInterface.Stub {
 * 4、当IBinder接口返回是新建的Messenger对象获取的IBinder时，它是一个远端服务，用来为其他进程提供单线程跨进程通信通道，如：new Messenger(mHandler).getBinder();
 *
 *  aidl实现过程：https://blog.csdn.net/dakaniu/article/details/79412694?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79412694-blog-115956577.pc_relevant_antiscanv2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79412694-blog-115956577.pc_relevant_antiscanv2&utm_relevant_index=2
 */

public class AidlActivity extends Activity {
    private static final String TAG = "ServiceActivity";
    @BindView(R.id.start)
    Button start;
    @BindView(R.id.pause)
    Button pause;
    @BindView(R.id.resume)
    Button resume;
    @BindView(R.id.remote_service)
    Button remote_service;
    @BindView(R.id.remote_messenger)
    Button remote_messenger;

    private AudioPlayerService.MyBinder myBinder;
    private AudioPlayerService audioPlayerService;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = ((AudioPlayerService.MyBinder) service);
            //activity中给服务发指令，进行开启，暂停，重启
            myBinder.callStart();
            myBinder.callResume();
            myBinder.callPause();
            audioPlayerService = myBinder.getAudioPlayerService();
            audioPlayerService.setCallBack(new AudioPlayerService.CallBack() {
                @Override
                public void process(int process) {
                    //收到服务返回的数据刷新界面
                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private IMyAidlInterface iMyAidlInterface;
    private ServiceConnection remoteConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    private Messenger reply;
    private Messenger messenger;
    private final ServiceConnection messengerConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(AidlActivity.this, "bind success", Toast.LENGTH_SHORT).show();
            messenger = new Messenger(service);
        }
    };

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.d(TAG, "回调成功");
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        ButterKnife.bind(this);
//1、本应用activity与本应用服务通信
        //本应用的服务进行连接,完成activity和service间的通信，绑定完成后conn中进行互交
        Intent intent = new Intent();
        intent.setClass(this, AudioPlayerService.class);
        bindService(intent, conn, BIND_AUTO_CREATE);


//2、本应用与远端服务使用AIDL通信，适用于多线程与远端服务通信
        //本应用和其他应用的服务进行连接，通过AIDL，实现进程间通信
        //连接时一定要注意：
        // 1、远程的service要在manifest中注册，并且要并且export要设置为true！！！
        // 2、必须要显示调用才能起作用，调用方法如下。或者在manifest中给service设置名称，然后通过setAction在设置setClass 给intent
        // 3、与远程的互交参考上面activity和本应用的互交方式，原理相同

        // AIDL实现写法：
        // 1、服务端在main/java同级目录下新建main/aidl目录并新建同报名下的aidl接口，如：main/aidl/com/example/remoteservice/IMyAidlInterface.aidl
        // 2、服务端通过bindService启动服务返回这个aidl
        // 3、客户端也需要新建aidl接口，注意文件及目录是和服务端的一样，而不是和自己报名一样！！！
        // 4、客户端通过bindService启动服务返回这个aidl，通过aidl给服务端进程发送消息
        // 5、客户端和服务端的aidl就建立起了连接，它是解决进程间频繁灵活发送消息通信的，最大数据1M-8K，超过就会报错，所以不能用来大数据拷贝

        //实现AIDL通信，这里是客户端
        Intent remoteIntent = new Intent();
        remoteIntent.setClassName("com.example.remoteservice", "com.example.remoteservice.RemoteService");
        //intent.setClass(this, RemoteService.class);  其他应用class 无法直接访问
        bindService(remoteIntent, remoteConn, BIND_AUTO_CREATE);

//3、本应用与远端服务使用Messenger通信，适用于单线程与远端服务通信     https://www.ktanx.com/blog/p/629
        reply = new Messenger(handler);
        Intent messengerIntent = new Intent();
        intent.setClassName("com.example.remoteservice", "com.example.remoteservice.MessengerTestService");
        // 绑定服务
        bindService(messengerIntent, messengerConn, BIND_AUTO_CREATE);

    }


    @OnClick({R.id.start, R.id.pause, R.id.resume, R.id.remote_service, R.id.remote_messenger})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.start:
                myBinder.callStart();
                break;
            case R.id.pause:
                myBinder.callPause();
                break;
            case R.id.resume:
                myBinder.callResume();
                break;
            case R.id.remote_service:
                try {
                    iMyAidlInterface.remote("从客户端发送密码001");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            case R.id.remote_messenger:
                try {
                    Message msg = Message.obtain(null, 1);
                    // 设置回调用的Messenger，发送成功会在reply中回调过来
                    msg.replyTo = reply;
                    messenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}
